﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;


////基类(父类)
//class Person  
//{
//public:
//	// 进入校园/图书馆/实验室刷二维码等身份认证
//	void identity()
//	{
//		cout << "void identity()" << _name << endl;
//		cout << _age << endl; 
//	}
//protected:
//	string _name = "张三"; // 姓名
//	string _address; // 地址
//	string _tel; // 电话
//private:
//	int _age = 18; // 年龄	
//};
//
////派生类(子类)
//class Student : public Person
//{
//public:
//	// 学习
//	void study()
//	{
//		// ...
//		//cout << _age << endl; //父类的私有成员在子类中完全不可见，仅父类自己的成员函数可访问,子类不可直接访问
//		cout << _tel << endl; //受保护成员，子类内部可访问
//		identity();
//	}
//protected:
//	int _stuid; // 学号
//};
//
////派生类(子类)
//class Teacher : public Person
//{
//public:
//	// 授课
//	void teaching()
//	{
//		//...
//	}
//protected:
//	string title; // 职称
//};
//
//int main()
//{
//	Student s;
//	//s.study();
//	Teacher t;
//	s.identity();
//	t.identity();
//
//	return 0;
//}




////继承类模版
//template<class T>
//class Mystack : public std::vector<T>
//{
//public:
//	void push(const T& x)
//	{
//		// 基类是类模板时，需要指定⼀下类域，
//		// 否则编译报错:error C3861: “push_back”: 找不到标识符
//		// 因为stack<int>实例化时，也实例化vector<int>了
//		// 但是模版是按需实例化，push_back等成员函数未实例化，所以找不到
//		vector<T>::push_back(x);
//		//push_back(x);
//	}
//	void pop()
//	{
//		vector<T>::pop_back();
//	}
//	const T& top()
//	{
//		return vector<T>::back();
//	}
//	bool empty()
//	{
//		return vector<T>::empty();
//	}
//
//private:
//	// 隐藏vector的插入、删除等接口（仅在类内部不可见，外部仍可通过指针绕过）
//	using std::vector<T>::insert;
//	using std::vector<T>::erase;
//	using std::vector<T>::operator[];
//
//};
//
//int main()
//{
//	Mystack<int> st;
//	st.push(1);
//	st.push(2);
//	st.push(3);
//	while (!st.empty())
//	{
//		cout << st.top() << " ";
//		st.pop();
//	}
//	return 0;
//}















//class Person
//{
//protected:
//	string _name; // 姓名
//	string _sex; // 性别
//	int _age; // 年龄
//};
//
//class Student : public Person
//{
//public:
//	int _No; // 学号
//};
//
//int main()
//{
//	Student sobj;
//	// 1.派⽣类对象可以赋值给基类的指针/引⽤
//	Person* pp = &sobj;
//	Person& rp = sobj;
//	// 派生类对象可以赋值给基类的对象是通过调⽤后⾯会讲解的基类的拷⻉构造完成的
//	Person pobj = sobj;
//	//2.基类对象不能赋值给派⽣类对象，这⾥会编译报错
//	sobj = pobj;
//	return 0;
//}




//// Student的_num和Person的_num构成隐藏关系，可以看出这样代码虽然能跑，但是⾮常容易混淆
//class Person
//{
//protected:
//	string _name = "小李子"; // 姓名
//	int _num = 150429; // ⾝份证号
//};
//class Student : public Person
//{
//public:
//	void Print()
//	{		
//		cout << "身份证号：" << Person::_num << endl;
//		cout << "学号：" << _num << endl;
//	}
//protected:
//	int _num = 2023; // 学号
//};
//int main()
//{
//	Student s1;
//	s1.Print();
//
//	return 0;
//};


//class A
//{
//public:
//	void fun()
//	{
//		cout << "父类func()" << endl;
//	}
//};
//class B : public A
//{
//public:
//	void fun(int i)
//	{
//		cout << "子类func(int i)" << endl;
//	}
//};
//
//int main()
//{
//	B b;
//	b.fun(1);
//	b.A::fun(); //指定作用域
//
//	return 0;
//};             //A类和B类的两个func构成隐藏关系，因为它们的成员函数名相同


//class Base 
//{
//public:
//    int _a = 10;  //基类的变量_a
//};
//
//class Derived : public Base 
//{
//public:
//    double _a = 20.5;  //派生类的变量_a（与基类同名，隐藏基类的_a）
//};
//
//int main() 
//{
//    Derived d;
//    cout << d._a << endl;        // 输出 20.5 默认访问派生类的_a（基类的被隐藏）
//    cout << d.Base::_a << endl;  // 输出 10   通过基类域限定符访问被隐藏的基类_a
//    return 0;
//}


//class Base 
//{
//public:
//    void show(int x) 
//    {
//        cout << "Base::show(int): " << x << endl;  //基类的int版本
//    }
//};
//
//class Derived : public Base 
//{
//public:
//    void show(double x) 
//    {
//        cout << "Derived::show(double): " << x << endl; //派生类的double版本
//    }
//};
//
//int main() 
//{
//    Derived d;
//    d.show(10);        // 实际运行：输出 Derived::show(double): 10（int→double隐式转换）cout对double类型输出有简化显示的默认行为
//    d.show(3.14);      // 输出 Derived::show(double): 3.14（直接匹配double）
//    d.Base::show(10);  // 输出 Base::show(int): 10（显式访问基类被隐藏的函数）
//    return 0;
//}



//class A
//{
//public:
//    void fun()
//    {
//        cout << "func()" << endl;
//    }
//};
//class B : public A
//{
//public:
//    void fun(int i)
//    {
//        cout << "func(int i)" << i << endl;
//    }
//};
//int main()
//{
//    B b;
//    b.fun(10);
//    b.fun();
//    return 0;
//};



//class Person
//{
//public:
//    Person(const char* name = "peter")
//        : _name(name)
//    {
//        cout << "Person()" << endl;
//    }
//   
//protected:
//    string _name; // 姓名
//};
//
//class Student : public Person
//{
//public:
//    Student(const char* name, int num)
//        : Person(name) //显式调用父类的构造函数
//        , _num(num)
//    {
//        cout << "Student()" << endl;
//    }
//   
//protected:
//    int _num; //学号
//};
//
//int main()
//{
//    Student s1("jack", 18);
//    Student s2(s1);
//
//
//
//
//   /* Student s2(s1);
//    Student s3("rose", 17);
//    s1 = s3;*/
//    return 0;
//}




//class Base //基类
//{
//public:
//    Base() { cout << "Base 构造" << endl; }
//
//    // 非虚析构（错误示范）
//    // ~Base() { cout << "Base 析构" << endl; }
//
//    // 虚析构（正确做法）
//    virtual ~Base() { cout << "Base 析构" << endl; }
//};
//
//class Derived : public Base  //派生类
//{
//private:
//    int* data;   //派生类动态资源
//public:
//    Derived() : data(new int(10)) { cout << "Derived 构造" << endl; }
//    ~Derived() //派生类析构：先释放自身资源，再调用基类析构
//    {
//        delete data;  //释放派生类资源
//        cout << "Derived 析构" << endl;
//    }
//};
//
//int main() 
//{
//    Base* ptr = new Derived(); //基类指针指向派生类对象
//    delete ptr;   //销毁对象
//    return 0;
//}





//class Base //基类
//{
//protected:
//    int base_val;
//public:
//    // 构造函数
//    Base(int val = 0) : base_val(val) {}
//
//    // 基类赋值运算符重载
//    Base& operator=(const Base& rhs) 
//    {
//        if (this == &rhs) return *this; // 处理自赋值
//        base_val = rhs.base_val; // 赋值基类成员
//        return *this;
//    }
//
//    void print() const 
//    {
//        std::cout << "Base value: " << base_val << std::endl;
//    }
//};
//
//// 派生类
//class Derived : public Base 
//{
//private:
//    char* derived_str; // 派生类独有的动态资源
//public:
//     //构造函数
//    Derived(int val = 0, const char* str = "") : Base(val) {
//        derived_str = new char[strlen(str) + 1];
//        strcpy(derived_str, str);
//    }
//
//    // 析构函数：释放动态资源
//    ~Derived() 
//    {
//        delete[] derived_str;
//    }
//
//    // 派生类赋值运算符重载
//    Derived& operator=(const Derived& rhs) 
//    {
//        if (this == &rhs) return *this; //处理自赋值
//
//        // 1. 调用基类的赋值运算符，处理基类成员
//        Base::operator=(rhs);
//
//        // 2. 处理派生类独有的成员（动态资源）
//        delete[] derived_str; //先释放当前资源
//        derived_str = new char[strlen(rhs.derived_str) + 1];
//        strcpy(derived_str, rhs.derived_str);
//
//        return *this;
//    }
//
//    void print() const 
//    {
//        Base::print();  //调用基类的print
//        std::cout << "Derived string: " << derived_str << std::endl;
//    }
//};
//
//int main() 
//{
//    Derived d1(10, "hello");
//    Derived d2(20, "world");
//
//    d1 = d2; // 调用派生类的operator=
//
//    d1.print();
//    // 输出：
//    // Base value: 20
//    // Derived string: world
//
//    return 0;
//}


//
////基类：仅包含基本类型和std::string
//class Person 
//{
//public:
//    std::string name;  // 标准库类型，自带资源管理
//    int age;           // 基本类型
//};
//
////派生类：继承自Person，新增基本类型和std::string成员
//class Student : public Person 
//{
//public:
//    std::string school;  // 标准库类型
//    double score;        // 基本类型
//};
//
//int main() 
//{
//    // 创建对象（依赖默认构造函数）
//    Student s1;
//    s1.name = "Alice";
//    s1.age = 18;
//    s1.school = "Sunny High";
//    s1.score = 95.5;
//
//    // 拷贝赋值（依赖编译器生成的默认赋值运算符）
//    Student s2;
//    s2 = s1;  // 自动完成基类成员(name, age)和派生类成员(school, score)的赋值
//
//    // 验证赋值结果
//    std::cout << "s2信息：" << std::endl;
//    std::cout << "姓名：" << s2.name << std::endl;
//    std::cout << "年龄：" << s2.age << std::endl;
//    std::cout << "学校：" << s2.school << std::endl;
//    std::cout << "成绩：" << s2.score << std::endl;
//
//    return 0;




//// 声明为 final，不可被继承
//class FinalClass final 
//{
//public:
//    void print() 
//    {
//        std::cout << "This is a final class." << std::endl;
//    }
//};
//
//// 尝试继承 FinalClass，编译报错
//// class Derived : public FinalClass {}; // 错误：无法从最终类继承
//
//int main() 
//{
//    FinalClass obj;
//    obj.print();
//    return 0;
//}


//
////兼容所有 C++ 标准，无语法依赖。
//class Base
//{
//public:
//	void func5() { cout << "Base::func5" << endl; }
//protected:
//	int a = 1;
//private:	
//	Base()  //将基类的构造函数私有
//	{}
//};
//
//class Derive :public Base
//{
//	void func4() { cout << "Derive::func4" << endl; }
//protected:
//	int b = 2;
//};
//int main()
//{
//	//Derive d;  //error！
//	return 0;
//}


//class Student; //声明一下
//
//class Person
//{
//public:
//	friend void Display(const Person& p, const Student& s);
//protected:
//	string _name; // 姓名
//};
//
//class Student : public Person
//{
//protected:
//	int _stuNum; // 学号
//};
//
//void Display(const Person& p, const Student& s)
//{
//	cout << p._name << endl;
//	//cout << s._stuNum << endl;//error! // 编译报错：error C2248: “Student::_stuNum”: ⽆法访问 protected 成员 
//	                                     //友元关系不能被继承，Display不是派生类Student的友元，不能访问它的成员
//										 //解决办法：将Display也变成Student的友元
//}
//
//int main()
//{
//	Person p;
//	Student s;	
//	Display(p, s);
//	return 0;
//}


////基类
//class Person
//{
//public:
//	string _name;
//	static int _count;
//};
//
//int Person::_count = 0; //类外初始化
//
////派生类
//class Student : public Person
//{
//protected:
//	int _stuNum;
//};
//
//int main()
//{
//	Person p;
//	Student s;	
//	
//	cout << &p._name << endl; 
//	cout << &s._name << endl;
//	
//	cout << &p._count << endl;
//	cout << &s._count << endl;
//
//	// 公有的情况下，⽗派⽣类指定类域都可以访问静态成员
//	cout << Person::_count << endl;
//	cout << Student::_count << endl;
//	cout << p._count << endl;
//	cout << s._count << endl;
//
//	return 0;
//}




//class Person
//{
//public:
//	string _name; // 姓名
//};
//
//class Student :  public Person
//{
//protected:
//	int _num; //学号
//};
//
//class Teacher :  public Person
//{
//protected:
//	int _id; // 职工编号
//};
//
//class Assistant : public Student, public Teacher
//{
//protected:
//	string _majorCourse; // 主修课程
//};
//
//int main()
//{	
//	Assistant a;
//	//a._name = "peter";  //error！编译报错：error C2385: 对“_name”的访问不明确
//
//	return 0;
//}





//class Person
//{
//public:
//	string _name; // 姓名
//};
//
//class Student : virtual public Person  //虚继承Person类
//{
//protected:
//	int _num; //学号
//};
//
//class Teacher : virtual public Person   //虚继承Person类
//{
//protected:
//	int _id; // 职工编号
//};
//
//class Assistant : public Student, public Teacher
//{
//protected:
//	string _majorCourse; // 主修课程
//};
//
//int main() 
//{
//    Assistant a;        //使用虚继承，可以解决数据冗余和⼆义性
//    a._name = "Peter";  //现在访问_name不再有歧义，因为只有一份Person实例
//
//    cout << a.Student::_name << endl;  // 输出 Peter
//    cout << a.Teacher::_name << endl;  // 输出 Peter    
//    //最终Assistant对象中只存在一份Person实例，Student、Teacher以及Assistant访问的_name，本质上都是同一份变量
//
//    return 0;
//}
//
////在虚继承结构中，最终派生类Assistant会主动创建并管理唯一一份Person实例





//class Base1 { public: int _b1; };
//class Base2 { public: int _b2; };
//class Derive : public Base1, public Base2 { public: int _d; };
//
//int main()
//{
//	Derive d;
//	Base1* p1 = &d;
//	Base2* p2 = &d;
//	Derive* p3 = &d;
//	return 0;
//}


////基类
//class Animal 
//{
//protected:
//    string name;
//public:
//    Animal(string n) : name(n) {}
//    void eat() {
//        cout << name << " is eating." << endl;
//    }
//};
//
////派生类
//class Dog : public Animal  //public继承
//{  
//public:
//    Dog(string n) : Animal(n) {}
//
//    void bark() 
//    {
//        cout << name << endl;
//    }
//
//};


//template<class T>
//class Mystack : public std::vector<T>
//{
//public:
//	void push(const T& x)
//	{
//		//push_back(x); error! 编译报错:error C3861: “push_back”: 找不到标识符
//		vector<T>::push_back(x); //right!基类是类模板时，需要指定⼀下类域
//		this->push_back(x);     //两种写法等效 this的类型依赖T，延迟到第二阶段模板实例化时，再去基类中查找该成员
//	}
//	void pop()
//	{
//		vector<T>::pop_back();
//		this->pop_back();
//
//	}
//	const T& top()
//	{
//		return vector<T>::back();
//	}
//	bool empty()
//	{
//		return vector<T>::empty();
//	}
//
//};
//
//int main()
//{
//	Mystack<int> st;
//	st.push(1);
//	st.push(2);
//	st.push(3);
//	while (!st.empty())
//	{
//		cout << st.top() << " ";
//		st.pop();
//	}
//	return 0;
//}


